Перейти к основному содержимому

Синтаксис и пунктуация в Rust

Разработчику Архитектору

Синтаксис и пунктуация в Rust

Двойные кавычки и строки

Двойные кавычки (") служат маркером начала и конца строковых литералов. Компилятор Rust интерпретирует текст внутри таких кавычек как последовательность байтов, представляющую собой строку типа &str (строка-ссылка) или String (владение строкой).

let name = "Alice";
let greeting = "Hello, world!";

Строки, заключенные в двойные кавычки, могут содержать специальные символы, такие как перенос строки \n, табуляцию \t или обратный слэш \\. Компилятор автоматически обрабатывает эти экранированные последовательности при создании строкового объекта. Строковые литералы являются неизменяемыми по умолчанию и хранятся в сегменте памяти кода.


Одинарные кавычки и символы

Одинарные кавычки (') предназначены исключительно для обозначения литералов типа char. Символ внутри одинарных кавычек представляет собой один Unicode скалярный код. Размер такого символа всегда фиксирован и составляет 4 байта в памяти.

let letter = 'A';
let emoji = '🚀';
let digit = '7';

В отличие от строк, которые могут содержать множество символов, char всегда хранит ровно один графем. Это свойство позволяет Rust эффективно работать с международными текстами, включая сложные символы из разных языков и эмодзи, без необходимости дополнительной обработки.


Апострофы и их отсутствие

Символ апострофа (), часто используемый в естественном языке для сокращений или притяжательных падежей, не имеет синтаксического значения в языке программирования Rust. Использование этого знака в коде приводит к ошибке компиляции, так как компилятор ожидает строго определенные грамматические конструкции.

Разработчики должны использовать только стандартные кавычки (" и ') и другие знаки препинания, описанные в спецификации языка. Попытка внедрить типографские варианты знаков, такие как правый апостроф, нарушит структуру программы.


Точка доступа к членам

Точка (.) является оператором доступа к полям структур и вызова методов объектов. Этот символ связывает экземпляр структуры или значение со своими внутренними компонентами.

struct Point {
x: i32,
y: i32,
}

let p = Point { x: 10, y: 20 };
println!("X coordinate: {}", p.x);
println!("Y coordinate: {}", p.y);

В примере выше выражение p.x обращается к полю x экземпляра p. Аналогично работает вызов методов, например string.len(), где точка отделяет имя переменной от имени метода. Без точки компилятор не сможет определить контекст обращения к данным.


Запятая разделения элементов

Запятая (,) выполняет функцию разделителя в списках элементов. Она используется при объявлении массивов, перечислении аргументов функций, определении полей структур и разделении переменных в присваивании.

let numbers = [1, 2, 3, 4, 5];

fn calculate(a: i32, b: i32, c: i32) -> i32 {
a + b + c
}

let result = calculate(10, 20, 30);

В массиве запятые отделяют значения друг от друга. В сигнатуре функции они разделяют параметры. При объявлении нескольких переменных в одной строке запятая также служит разделителем. Отсутствие запятой между элементами приведет к синтаксической ошибке.


Точка с запятой завершение выражений

Точка с запятой (;) является обязательным завершающим знаком для большинства инструкций в блоке кода. Она сообщает компилятору о том, что выражение завершено и результат может быть обработан или проигнрирован.

let x = 5;
let y = 10;
let sum = x + y;

println!("The sum is: {}", sum);

В Rust точка с запятой преобразует выражение в инструкцию. Выражение без точки с запятой возвращает значение, которое может быть использовано дальше. Инструкция с точкой с запятой не возвращает значение (или возвращает единицу ()). Пропуск этой точки после объявления переменной или вызова функции вызовет ошибку синтаксиса.


Подчеркивание и соглашения именования

Нижнее подчеркивание (_) в Rust имеет несколько специфических применений, связанных с управлением вниманием компилятора и структурой кода.

Использование _name указывает на то, что переменная объявлена, но её значение не будет использоваться в дальнейшем. Это предотвращает генерацию предупреждений компилятора о неиспользуемых переменных.

let _unused_variable = "This value will not be used";

Компилятор игнорирует предупреждения для идентификаторов, начинающихся с подчеркивания, если они не используются. Однако это соглашение не влияет на приватность доступа. Приватность в Rust определяется ключевым словом pub или его вариациями (pub(crate)), а не наличием подчеркивания.

Самостоятельное использование одиночного подчеркивания (_) означает полное игнорирование соответствующего элемента в деструктуризации или сопоставлении с образцом.

let (first, _, third) = (10, 20, 30);
// Значение 20 игнорируется

Здесь переменная _ заменяет второе значение кортежа, так как оно не требуется программе.


Числовые литералы и читаемость

Подчеркивание допустимо внутри числовых литералов для улучшения визуального восприятия больших чисел. Разделители помогают быстро оценить порядок величины числа.

let million = 1_000_000;
let gigabyte = 1_073_741_824;
let binary_value = 0b1010_1010;

Компилятор полностью игнорирует подчеркивания внутри чисел при компиляции. Результат вычислений идентичен результату при отсутствии разделителей. Такой подход повышает читаемость кода и снижает риск опечаток при вводе длинных констант.


Плейсхолдер в сопоставлении с образцом

В конструкции match символ _ выступает в роли плейсхолдера, который соответствует любому значению, не попавшему в предыдущие ветви условия. Это аналог блока else в условных операторах.

let value = 5;

match value {
1 => println!("One"),
2 => println!("Two"),
3 => println!("Three"),
_ => println!("Something else or default"),
}

Если значение value равно 1, 2 или 3, выполняется соответствующая ветка. Если значение другое, выполняется блок под _. Это обеспечивает обработку всех возможных случаев и предотвращает ошибки времени выполнения из-за непредвиденных значений.


Побитовое ИЛИ и замыкания

Символ вертикальной черты (|) выполняет две различные роли в зависимости от контекста использования.

Первая роль — побитовое ИЛИ. Оператор применяет операцию поразрядного сложения к целочисленным типам данных.

let x = 5 | 3; // Результат 7 (101 | 011 = 111)

Второй ролью является определение границ параметров замыкания (closures). Параметры замыкания оборачиваются в вертикальные черты.

let double = |x: i32| x * 2;
let result = double(5); // 10

Выражение |x| обозначает начало списка параметров замыкания и его конец. Внутри этих черт можно указать типы параметров и их количество. Если параметров нет, используют пустые черты ||.


Логическое ИЛИ

Две вертикальные черты (||) представляют собой оператор логического ИЛИ. Он применяется к булевым значениям и возвращает истину, если хотя бы одно из условий истинно.

let a = true;
let b = false;

if a || b {
println!("At least one condition is true");
}

Этот оператор отличается от побитового ИЛИ тем, что работает с логическими типами, а не с битами чисел. Он часто используется в условиях циклов и условных операторов для проверки нескольких критериев одновременно.


Сравнение операций с похожими символами

Важно различать операции с одним и двумя знаками. Одиночная черта | для битовых операций и параметров замыкания. Двойная черта || исключительно для логики. Путаница между этими операторами приводит к ошибкам логики программы или ошибкам компиляции.

Компилятор Rust строго проверяет контекст использования каждого знака. Использование | вместо || в условии if вызовет ошибку, так как ожидается булев тип, а получен целый. Использование || вместо | в побитовой операции также невозможно из-за разницы в семантике.


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).